#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

import json

import pexpect

from common.common_models import ActionResult
from common.const import ExecuteResultEnum, AuthType
from common.exception.common_exception import ErrCodeException
from common.util.check_user_utils import check_os_user
from gaussdbt.single import LOGGER
from gaussdbt.single.comm.gst_single_error_code import ErrorCode
from gaussdbt.single.comm.utils.gst_single_comm_utils import GstSingleCommonUtil
from gaussdbt.single.comm.utils.gst_single_param_utils import GstSingleParamUtil
from gaussdbt.single.resource.gst_resource_base import GstResourceBase


class GstSingleResource(GstResourceBase):
    def __init__(self, pid, param_dict):
        super().__init__(pid, param_dict)
        self.os_user = GstSingleParamUtil.get_os_user_name(self.pid)
        self.sys_auth_type = GstSingleParamUtil.get_sys_auth_type(self.param_dict)
        self.sys_auth_pwd = GstSingleParamUtil.get_sys_auth_pwd(self.pid)

    def exec_check_application(self):
        # 检查用户名
        if not check_os_user(self.os_user):
            LOGGER.error(f"This Os user name is incorrect. os user: %s", self.os_user)
            return GstSingleCommonUtil.build_action_result(code=ExecuteResultEnum.INTERNAL_ERROR.value,
                                                           body_err=ErrorCode.USER_IS_NOT_EXIST)

        # 检查数据库服务
        if not GstSingleCommonUtil.check_gaussdbt_single_service(self.os_user):
            LOGGER.error(f"Check gaussdbt single service failed.")
            return GstSingleCommonUtil.build_action_result(code=ExecuteResultEnum.INTERNAL_ERROR.value,
                                                           body_err=ErrorCode.DB_SERVICE_ERROR)

        # 检查认证信息
        gsdb_home = GstSingleCommonUtil.get_val_of_gsdb_env_var(self.os_user, "GSDB_HOME")
        gsdb_data = GstSingleCommonUtil.get_val_of_gsdb_env_var(self.os_user, "GSDB_DATA")
        check_ret, out = GstSingleCommonUtil.check_gsdb_auth(self.os_user, gsdb_home, gsdb_data,
                                                             self.sys_auth_type, sys_pwd=self.sys_auth_pwd)
        if not check_ret:
            LOGGER.error(f"This check gaussdbt auth failed.")
            return out

        # 检查数据库状态
        enable_sysdba_login = (str(self.sys_auth_type) != str(AuthType.APP_PASSWORD.value))
        try:
            GstSingleCommonUtil.check_gsdb_status(
                self.os_user, gsdb_home, gsdb_data, enable_sysdba_login=enable_sysdba_login, sys_pwd=self.sys_auth_pwd)
        except ErrCodeException:
            return GstSingleCommonUtil.build_action_result(code=ExecuteResultEnum.INTERNAL_ERROR.value,
                                                           body_err=ErrorCode.ERR_DATABASE_STATUS)

        # 查询版本
        version = GstSingleCommonUtil.get_gsdb_version(self.os_user)
        if not version:
            return GstSingleCommonUtil.build_action_result(code=ExecuteResultEnum.INTERNAL_ERROR.value,
                                                           body_err=ErrorCode.OPERATION_FAILED)
        LOGGER.info(f"Execute gaussdbt single check application success.")
        return ActionResult(code=ExecuteResultEnum.SUCCESS.value, message=json.dumps({"version": version}))
